-- TODO: make a "Package" à la ENGINE_DS , e.g. ENGINE_DS:testpaint etc

--Globals
SCREEN_WIDTH = 250
SCREEN_HEIGHT = 192

tmr = Timer.new()
tmr:start()
clock = {}
ohtList = {}
-- Testthings
testimage = Image.load("resources/default.png", VRAM)
testimagegif = Image.load("resources/point.gif", VRAM)
testsprite = Sprite.new ("resources/char.png", 24,32,VRAM)
testsprite:addAnimation( {0,1,2,1}, 300 ) -- 1

-- can be used for "benchmarking"
function testpaint()
  screen.blit(SCREEN_DOWN, hero.x + math.random(-40,40), hero.y + math.random(-40,40), testimagegif)
end
 
function paint_ds(o)
	-- 0. check if there is a current action TODO, really nice to have
	--if o.paint.states[o.currentState.name].actions[o.currentaction.name].sprite then
	-- do nothing
	-- 1. check if currentState has sprite loaded
	if o.paint and o.paint.states and o.paint.states[o.currentState.name] then
		if o.paint.states[o.currentState.name].sprite then
			paintSprite(o,o.paint.states[o.currentState.name].sprite)
	    -- NOTE: testing
			screen.print(SCREEN_DOWN, o.x, o.y, '') --cs 
	-- 2. check if currentState has image loaded to paint
	 	elseif o.paint.states[o.currentState.name].image then
			paintImage(o,o.paint.states[o.currentState.name].image)
	    -- NOTE: testing
	  	screen.print(SCREEN_DOWN, o.x, o.y, '') --ci 
	  end
	elseif o.paint then
	-- 3. check if there is an default sprite to paint
	  if o.paint.sprite then
			paintSprite(o, o.paint.sprite)
	    -- NOTE: testing
			screen.print(SCREEN_DOWN, o.x, o.y, '') --di
	-- 4. check if default image loaded to paint
	  elseif o.paint.image then
			paintImage(o,o.paint.image)
	    -- NOTE: testing
	    screen.print(SCREEN_DOWN, o.x, o.y, '') --di
	-- last: if no image / sprite is available paint text "no img"
	  else
	  -- TODO: if no pic ?
	    screen.print(SCREEN_DOWN, o.x, o.y, 'no img') 
	  end
	end
	-- screen.print(SCREEN_DOWN,o.x,o.y + 10,o.currentState.name)
end

function clock.run()
	clock.time = tmr:time()
	clock.hour = math.floor(clock.time/3600000)
	clock.rest = clock.time % 3600000
	clock.minut = math.floor(clock.time/60000)
	clock.rest = clock.rest % 60000
	clock.second = math.floor(clock.rest/1000)
	clock.rest = clock.rest % 1000
	clock.milli = clock.rest
end

function paint_ds_layer1() 
    screen.blit(SCREEN_DOWN,0,0, background)
end

function paint_ds_layer3() 
	screen.print(SCREEN_UP, 0,30, "Leben :"..hero.hp)
	screen.print(SCREEN_UP, 0,50, "Mana: "..hero.mana)
	screen.print(SCREEN_UP, 0,110, "X: "..hero.x)
	screen.print(SCREEN_UP, 0,130, "Y: "..hero.y)
	screen.print(SCREEN_UP, 0,90, NB_FPS)
	screen.print(SCREEN_UP, 0,100, hero.exp)
	--screen.print(SCREEN_UP, 0,150, hero.currentState.name) <----
	screen.print(SCREEN_UP, 70,10, '#'..#gameelements)
--[[	screen.print(SCREEN_UP, 70,30, 'A'..controls.newPress.button1) 
	screen.print(SCREEN_UP, 70,40, 'B'..controls.newPress.button2) 
	screen.print(SCREEN_UP, 70,50, 'X'..controls.newPress.button3) 
	screen.print(SCREEN_UP, 70,60, 'Y'..controls.newPress.button4) 
	screen.print(SCREEN_UP, 70,70, 'L'..controls.newPress.button5) 
	screen.print(SCREEN_UP, 70,80, 'R'..controls.newPress.button6) 
	screen.print(SCREEN_UP, 70,90, '<-'..controls.newPress.left) 
	screen.print(SCREEN_UP, 70,100, '->'..controls.newPress.right) 
	screen.print(SCREEN_UP, 70,110, '/\\ '..controls.newPress.up) 
	screen.print(SCREEN_UP, 70,120, '\\/'..controls.newPress.down) --]]
	if hero then
	screen.print(SCREEN_UP, 0,140, 'herostate => '..hero.currentState.name)
	end 
	--screen.print(SCREEN_UP, 0,100, hero.save.status.life)
	-- tests von jan
	for _,t  in ipairs(gameelements) do
		screen.print(SCREEN_DOWN, t.x, t.y - 7, t.currentState.name)
	end
	
	for i= 1,#hero.inventory[1] do
		if hero.inventory[1][i].item then
			screen.print(SCREEN_UP, 80, (10*i) + 10, hero.inventory[1][i].item.name)
		end
	end
end

function imageload_ds()
  -- background
  local ram
  ram = VRAM
  background = Image.load("resources/background.png", ram)
  -- element images/sprites load
  for _,paintable in ipairs(paintable_objects) do
  	-- TODO: rawget (-> ignores metatable, no inheritance)? or no image/sprite for gameelement?	    
		-- test TODO: just debug 
		print("try load graphic for "..paintable.name)
	  paintable.paint = {}

		-- loading state sprites / images
		paintable.paint.states = {}
		-- load sprites for states
		if paintable.sprite then
			if paintable.sprite.states then
				for s,_ in pairs(paintable.sprite.states) do
					paintable.paint.states[s] = {}
					loadSprite(paintable.paint.states[s], paintable.sprite.states[s], ram)
					-- test TODO: just debug 
					print("could load state sprite")
				end
			end
		-- load images for states
		elseif paintable.image then
			if paintable.image.states then
				-- TODO: possible workaround for 
				-- paintable.image.states["dead"] = {}
				-- table.insert(paintable.image.states["dead"], "resources/gravestone.png")
				for s,_ in pairs(paintable.image.states) do
					paintable.paint.states[s] = paintable.paint.states[s] or {}
					paintable.paint.states[s].image = {}
					loadImage(paintable.paint.states[s].image, paintable.image.states[s], ram)
					-- test TODO: just debug 
					print("could load state image: [1] "..paintable.image.states[s][1])
				end
			end
		end
		-- TODO load sprites/images for actions of states to paintabl.paint.states.sprite / image.default/direction
  	if paintable.sprite and not(#paintable.sprite == 0) then
			loadSprite(paintable.paint, paintable.sprite, ram)
					-- test TODO: just debug 
			print("could load normal sprite")
		elseif paintable.image then
	    paintable.paint.image = {}
			loadImage(paintable.paint.image, paintable.image, ram)
					-- test TODO: just debug 
					print("could load normal image")
  	else -- if no image and no sprite is set
  	-- do nothing?
		-- test TODO: just debug 
		print("couldnt load anything")
  	end
	end
end

function paintOht()
	for i, v in pairs(ohtList) do
		if v.countDown:check() then
			screen.print(SCREEN_DOWN,v.x,v.y,v.text)
			v.y = v.y - v.speed
		else
			table.remove(ohtList, i)
		end
	end
end
-- ============== Helper Functions
-- help function to load sprites
function loadSprite(target, from, ram)
	target.sprite = Sprite.new (from.image, from.width, from.height, ram)
	for k,v in ipairs(from) do
		target.sprite:addAnimation( v.animation, v.duration )
		-- there aren't more then 8
		if k == 8 then break end
	end
end
-- help function to load Images
function loadImage(target, from, ram)
	for k,v in ipairs(from) do
		if from[k] then
			target[k] = Image.load(v, ram)
		end
	end
	-- fill up images that aren't avaible
	if from[1] then
	if not target[2] then --default image. 1.test south
		target[2] = Image.load(from[1], ram)
		target[3] = Image.load(from[1], ram)
		target[4] = Image.load(from[1], ram)
		target[5] = Image.load(from[1], ram)
		target[6] = Image.load(from[1], ram)
		target[7] = Image.load(from[1], ram)
		target[8] = Image.load(from[1], ram)
	elseif not target[3] then
		target[3] = Image.load(from[1], ram)
		target[4] = Image.load(from[1], ram)
		target[5] = Image.load(from[2], ram)
		target[6] = Image.load(from[2], ram)
		target[7] = Image.load(from[1], ram)
		target[8] = Image.load(from[1], ram)
	elseif not target[4] then
		target[4] = Image.load(from[3], ram)
		target[5] = Image.load(from[2], ram)
		target[6] = Image.load(from[2], ram)
		target[7] = Image.load(from[3], ram)
		target[8] = Image.load(from[3], ram)
	elseif not target[5] then
		target[5] = Image.load(from[2], ram)
		target[6] = Image.load(from[2], ram)
		target[7] = Image.load(from[4], ram)
		target[8] = Image.load(from[4], ram)
	elseif not target[6] then
		target[6] = Image.load(from[2], ram)
		target[7] = Image.load(from[4], ram)
		target[8] = Image.load(from[4], ram)
	elseif not target[7] then
		target[7] = Image.load(from[4], ram)
		target[8] = Image.load(from[4], ram)
	elseif not target[8] then
		target[8] = Image.load(from[4], ram)
	end
	end
end
function paintSprite(object, sprite)
	local o = object
			if o.sprite[o.direction] then
				sprite:playAnimation(SCREEN_DOWN, o.x, o.y, o.direction)
			elseif o.sprite[3] then --default sprite. 1.test south
				sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 3) --south
			else --default sprite. 2.first avaible
				sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 1) --north
      end
end

function paintImage(object, from)
	local o = object
		if from[o.direction] then
			screen.blit(SCREEN_DOWN, o.x, o.y, from[o.direction])
		-- NOTE: leave this. benchmarking if this is better or do it in loadImages
--[[		elseif (o.direction == 5 or o.direction == 6) and from[2] then --default image. 1.test south
		  screen.blit(SCREEN_DOWN, o.x, o.y, from[2])
		elseif (o.direction == 7 or o.direction == 8) and from[4] then --default image. 1.test south
		  screen.blit(SCREEN_DOWN, o.x, o.y, from[4])
		elseif from[3] then --default image. 1.test south
		  screen.blit(SCREEN_DOWN, o.x, o.y, from[3])
		elseif from[1] then--default sprite. 2.first avaible
		  screen.blit(SCREEN_DOWN, o.x, o.y, from[1])--]]
		else
			print(o.name.." couldnt be painted")
		end
	--end
--[[ TODO: nice to have: autoflip things when not avaible ... 
				if true then	
				-- if there is an image for EAST but not for WEST, flip it
				elseif v == "east" and paintable.image["west"] then
				-- TODO
				Image.mirrorH(
				-- if there is an image for WEST but not for EAST flip it
				elseif v == "west" and paintable.image["east"] then
				-- TODO	
				end
--]]
end


--[[ old stuff
	  	if o.direction == 'north' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 1)
	  	elseif o.direction == 'northeast' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 2)
	  	elseif o.direction == 'east' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 3)
	  	elseif o.direction == 'southeast' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 4)
	  	elseif o.direction == 'south' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 5)
	  	elseif o.direction == 'southwest' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 6)
	  	elseif o.direction == 'west' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 7)
	  	elseif o.direction == 'northwest' then o.paint.sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 8)
--]]
--[[ new shit
	local counter = 1
	if o.direction == 'north' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'northeast' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'east' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'southeast' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'south' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'southwest' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'west' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	elseif o.direction == 'northwest' then sprite:playAnimation(SCREEN_DOWN, o.x, o.y, counter); counter = counter + 1
	else -- paint default
		sprite:playAnimation(SCREEN_DOWN, o.x, o.y, 0)
	end
--]]

function controlsupdate_ds()
	Controls.read() 
  --TODO: add Stylus controls => Stylus = Mouse
  -- buttons: A,B,X,Y,L,R,UP,DOWN,LEFT,RIGHT,Start,Select
  -- states: held, pressed, released
	--controls.newPress = {}
	--controls.released = {}
	--controls.held = {}
	controls.released.button1 = Keys.released.A
	controls.released.button2 = Keys.released.B
	controls.released.button3 = Keys.released.X
	controls.released.button4 = Keys.released.Y
	controls.released.button5 = Keys.released.L
	controls.released.button6 = Keys.released.R
	controls.released.right = Keys.released.Right
	controls.released.left = Keys.released.Left
	controls.released.up = Keys.released.Up
	controls.released.down = Keys.released.Down
	controls.released.start = Keys.released.Start
	controls.released.select = Keys.released.Select
	controls.held.button1 = Keys.held.A
	controls.held.button2 = Keys.held.B
	controls.held.button3 = Keys.held.X
	controls.held.button4 = Keys.held.Y
	controls.held.button5 = Keys.held.L
	controls.held.button6 = Keys.held.R
	controls.held.right = Keys.held.Right
	controls.held.left = Keys.held.Left
	controls.held.up = Keys.held.Up
	controls.held.down = Keys.held.Down
	controls.held.start = Keys.held.Start
	controls.held.select = Keys.held.Select
	controls.newPress.button1 = Keys.newPress.A
	controls.newPress.button2 = Keys.newPress.B
	controls.newPress.button3 = Keys.newPress.X
	controls.newPress.button4 = Keys.newPress.Y
	controls.newPress.button5 = Keys.newPress.L
	controls.newPress.button6 = Keys.newPress.R
	controls.newPress.right = Keys.newPress.Right
	controls.newPress.left = Keys.newPress.Left
	controls.newPress.up = Keys.newPress.Up
	controls.newPress.down = Keys.newPress.Down
	controls.newPress.start = Keys.newPress.Start
	controls.newPress.select = Keys.newPress.Select
end
